package com.wfh.frp;

import com.wfh.frp.coder.ProxyMsgDecoder;
import com.wfh.frp.coder.ProxMsgEncoder;
import com.wfh.frp.model.ProxyMsg;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class SimpleNettyServer {

    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO)) // 可选：记录连接事件
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline()
                                    // 注意顺序：先解码收到的数据，再处理；发送时先编码
                                    .addLast(new ProxyMsgDecoder())   // 解析客户端发来的 ProxyMsg
                                    .addLast(new ProxMsgEncoder())    // 如果你要回 ProxyMsg，需要编码器
                                    .addLast(new ProxyMsgServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(8080).sync();
            System.out.println("Netty 服务端已启动，监听端口: 8080");

            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    // 处理 ProxyMsg 消息的业务逻辑
    public static class ProxyMsgServerHandler extends SimpleChannelInboundHandler<ProxyMsg> {

        @Override
        protected void messageReceived (ChannelHandlerContext ctx, ProxyMsg msg) throws Exception {
            System.out.println("✅ 收到客户端 ProxyMsg: " + msg);

            // 示例：如果是 type=2（注册），可以记录 channelId
            if (msg.getType() == 2) {
                System.out.println("🆕 新客户端注册，channelId: " + msg.getChannelId());
                // 可选：回一个确认消息
                ProxyMsg ack = new ProxyMsg();
                ack.setType((byte) 4); // ACK 类型
                ack.setChannelId(msg.getChannelId());
                ctx.writeAndFlush(ack);
            }

            // 如果是 type=3（心跳），可以忽略或记录
            if (msg.getType() == 3) {
                System.out.println("💓 收到心跳，channelId: " + msg.getChannelId());
            }
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            System.err.println("❌ 服务端异常: " + cause.getMessage());
            cause.printStackTrace();
            ctx.close();
        }
    }
}